import 'dart:math';

import 'package:flutter/material.dart';

class CustomStarRoomPage extends StatefulWidget {
  @override
  _CustomStarRoomPageState createState() => _CustomStarRoomPageState();
}

class _CustomStarRoomPageState extends State<CustomStarRoomPage> with SingleTickerProviderStateMixin{

  Animation<double> _animation;
  AnimationController _animationController;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(vsync: this, duration: const Duration(seconds: 30));
    _animation = Tween<double>(begin: 0, end: 1.0).animate(_animationController);
    _animationController.addListener(() { 
      setState(() {
        
      });
    });
    _animationController.repeat();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    return Container(
      height: size.height,
      width: size.width,
      child: SizedBox(
        height: 300,
        width: size.width,
        child: CustomPaint(
          painter: _MineBall(beginAngle: 360 * _animation.value),
        ),
      )
    );
  }
}

class _MineBall extends CustomPainter {
  
  final double beginAngle;

  _MineBall({ this.beginAngle });
  /// 圆形
  Offset _circleComputeOffset(double angle, Offset center) {
    double radian = pi / 180.0 * (angle + beginAngle);

    final adius = 80;

    double x = center.dx + cos(radian) * adius;
    double y = center.dy + sin(radian) * adius;
    return Offset(x, y);
  }

  /// 椭圆
  Offset _ovalComputeOffset(double angle, Offset center) {
    double radian = pi / 180.0 * (angle + beginAngle);
    
    final ovalA = 120.0; // 长半径
    final ovalB = 40.0;   // 短半径

    Offset res;
    double x = ovalA * cos(radian);
    double y = ovalB * sin(radian);
    res = Offset(x, y);
    return Offset(res.dx + center.dx, res.dy + center.dy);
  }

  /// 斜椭圆
  Offset _ovalTitlComputeOffset(double angle, Offset center, {double ovalA = 80, double ovalB = 40.0, int titlAngle = -60}) {
    double radian = pi / 180.0 * (angle + beginAngle);
    
    // final ovalA = 80.0; // 长半径
    // final ovalB = 40.0;   // 短半径
    // final titlAngle = -60; // 倾斜角度

    Offset res;
    double x = ovalA * cos(radian) * cos(titlAngle) - ovalB * sin(radian) * sin(titlAngle);
    double y = ovalA * cos(radian) * sin(titlAngle) - ovalB * sin(radian) * cos(titlAngle);
    res = Offset(x, y);
    return Offset(res.dx + center.dx, res.dy + center.dy);
  }

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
    ..color = Colors.white
    ..style = PaintingStyle.fill;
    Offset center = Offset((size.width) / 2, size.height / 2.0);
    List<Color> arrColors = [Colors.red, Colors.cyan, Colors.redAccent, Colors.amber, Colors.pink, Colors.purple];
    for(int i = 0; i < 360; i += 10) {
      paint.color = arrColors[(i ~/ 10) % 4];
      canvas.drawCircle(_ovalTitlComputeOffset(i.toDouble(), Offset((size.width) / 2, size.height / 2.0), titlAngle:9,), 5, paint);
      canvas.drawCircle(_ovalTitlComputeOffset(i.toDouble(), Offset((size.width) / 2, size.height / 2.0), titlAngle:2, ovalB: 90), 2, paint);

    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }

}